package cn.flying.cloud.core.auth.handler;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSON;

import cn.flying.cloud.base.common.constants.Constants;
import cn.flying.cloud.base.common.enums.RtCodeEnum;
import cn.flying.cloud.base.common.exception.BizException;
import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.base.common.vo.Rt;
import cn.flying.cloud.core.auth.details.UserDetail;
import cn.flying.cloud.core.auth.utils.JwtUtil;
import cn.flying.cloud.system.common.service.UserService;
import cn.flying.cloud.system.log.entity.SysLoginLog;

/**
 * @description: 登录认证成功处理类  这里采用继承，可以继承默认的处理规则，这里可以根据不同判断实现不同的返回处理
 * @author: admin
 * @date: 2023年05月25日 12:37
 * @version: 1.0
 */
@Component
public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private UserService userService;

    /**
     * Called when a user has been successfully authenticated.
     *
     * @param request        the request which caused the successful authentication
     * @param response       the response
     * @param authentication the <tt>Authentication</tt> object which was created during
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //获取当登录用户信息
        UserDetail userDetail = (UserDetail) authentication.getPrincipal();
        if (Objects.isNull(userDetail)) {
            throw new BizException("没有获取到当前登录信息");
        }
        Date date = new Date();
        logger.info("租户ID【{}】的用户【{}-{}】登录系统成功！最后登录时间：【{}】", userDetail.getTenantId(), userDetail.getUserId(), userDetail.getUsername(), Ft.Date.formatDate(date, "yyyy-MM-dd HH:mm:ss"));

        userService.updateUserLoginTimeByUsername(userDetail.getUsername());

        //生成token
        String token = jwtUtil.generateToken(userDetail);

        try {
            //保存登录日志
            SysLoginLog log = new SysLoginLog();
            log.setUserId(userDetail.getUserId());
            log.setUserName(userDetail.getUsername());
            log.setName(userDetail.getName());
            log.setHappenType("用户登录");
            log.setHappenTime(LocalDateTime.now());
            log.setHappenIp(Ft.Network.getIpAddress(request));
            log.setRemark("用户登录成功");
            log.setTenantId(userDetail.getTenantId());
            log.setCreatedBy(userDetail.getUsername());
            log.setCreatedTime(LocalDateTime.now());
            log.setUpdatedBy(userDetail.getUsername());
            log.setUpdatedTime(LocalDateTime.now());
            log.setRevision(0L);
            userService.insertLoginLog(log);
        } catch (Exception e) {
            logger.warn("系统登录日志保存失败，异常原因【{}】", e.getMessage());
        }

        //将token放入缓存
        Ft.LocalCache.set(Constants.ACCESS_TOKEN, token);

        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        //登录成功返回用户信息（token）
        out.write(JSON.toJSONString(Rt.success(RtCodeEnum.R_SUCCESS.getDesc(), token)));
        out.flush();
        out.close();
    }
}
